﻿// Pull model smart tag example.
// Need references to System.dll, System.Windows.Forms.dll, 
// System.Design.dll, and System.Drawing.dll.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Text;
using System.Reflection;
using System.Windows.Forms.Design;
using System.Security.Permissions;

namespace SmartTags
{
    // ColorLabel is a simple extension of the standard Label control,
    // with color property locking added.
    [Designer(typeof(ColorLabelDesigner))]
    public partial class ColorLabel : System.Windows.Forms.Label
    {
        private bool colorLocked = false;

        public bool ColorLocked
        {
            get
            {
                return colorLocked;
            }
            set
            {
                colorLocked = value;
            }
        }

        public override Color BackColor
        {
            get
            {
                return base.BackColor;
            }
            set
            {
                if (ColorLocked)
                    return;
                else
                    base.BackColor = value;
            }
        }

        public override Color ForeColor
        {
            get
            {
                return base.ForeColor;
            }
            set
            {
                if (ColorLocked)
                    return;
                else
                    base.ForeColor = value;
            }
        }
    }

    // Designer for the ColorLabel control with support for a smart 
    // tag panel.
    // Must add reference to System.Design.dll
    [PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public class ColorLabelDesigner : ControlDesigner
    {
        private DesignerActionListCollection actionLists;
        // Use pull model to populate smart tag menu.
        public override DesignerActionListCollection ActionLists
        {
            get
            {
                if (null == actionLists)
                {
                    actionLists = new DesignerActionListCollection();
                    actionLists.Add(new ColorLabelActionList(this.Component));
                }
                return actionLists;
            }
        }
    }

    // DesignerActionList-derived class defines smart tag entries and
    // resultant actions.
    public class ColorLabelActionList : DesignerActionList
    {
        private ColorLabel colLabel;
        private DesignerActionUIService designerActionUISvc = null;

        public ColorLabelActionList(IComponent component) : base(component)
        {
            this.colLabel = component as ColorLabel;
            //用于刷新智能标记面板
            this.designerActionUISvc =  GetService(typeof(DesignerActionUIService)) as DesignerActionUIService;
        }

        // Helper method to retrieve control properties. Use of 
        // GetProperties enables undo and menu updates to work properly.
        private PropertyDescriptor GetPropertyByName(String propName)
        {
            PropertyDescriptor prop;
            prop = TypeDescriptor.GetProperties(colLabel)[propName];
            if (null == prop)
                throw new ArgumentException("Matching ColorLabel property not found!", propName);
            else
                return prop;
        }

        // Properties that are targets of DesignerActionPropertyItem entries.
        public Color BackColor
        {
            get
            {
                return colLabel.BackColor;
            }
            set
            {
                GetPropertyByName("BackColor").SetValue(colLabel, value);
            }
        }

        public Color ForeColor
        {
            get
            {
                return colLabel.ForeColor;
            }
            set
            {
                GetPropertyByName("ForeColor").SetValue(colLabel, value);
            }
        }


        // Boolean properties are automatically displayed with binary 
        // UI (such as a checkbox).
        public bool LockColors
        {
            get
            {
                return colLabel.ColorLocked;
            }
            set
            {
                GetPropertyByName("ColorLocked").SetValue(colLabel, value);
                // Refresh the list.
                this.designerActionUISvc.Refresh(this.Component);
            }
        }

        public String Text
        {
            get
            {
                return colLabel.Text;
            }
            set
            {
                GetPropertyByName("Text").SetValue(colLabel, value);
            }
        }

        //取反色
        public void InvertColors()
        {
            Color currentBackColor = colLabel.BackColor;
            BackColor = Color.FromArgb(
                255 - currentBackColor.R,
                255 - currentBackColor.G,
                255 - currentBackColor.B);

            Color currentForeColor = colLabel.ForeColor;
            ForeColor = Color.FromArgb(
                255 - currentForeColor.R,
                255 - currentForeColor.G,
                255 - currentForeColor.B);
        }

        // 重写父类的方法，实现在智能标签显示的属性
        public override DesignerActionItemCollection GetSortedActionItems()
        {
            DesignerActionItemCollection items = new DesignerActionItemCollection();

            //Define static section header entries.
            items.Add(new DesignerActionHeaderItem("Appearance"));
            items.Add(new DesignerActionHeaderItem("Information"));

            //Boolean property for locking color selections.
            items.Add(new DesignerActionPropertyItem("LockColors",
                             "Lock Colors", "Appearance",
                             "Locks the color properties."));
            if (!LockColors)
            {
                items.Add(new DesignerActionPropertyItem("BackColor",
                                 "Back Color", "Appearance",
                                 "Selects the background color."));
                items.Add(new DesignerActionPropertyItem("ForeColor",
                                 "Fore Color", "Appearance",
                                 "Selects the foreground color."));

                //This next method item is also added to the context menu 
                // (as a designer verb).
                items.Add(new DesignerActionMethodItem(this,
                                 "InvertColors", "Invert Colors",
                                 "Appearance",
                                 "Inverts the fore and background colors.",
                                  true));
            }
            items.Add(new DesignerActionPropertyItem("Text",
                             "Text String", "Appearance",
                             "Sets the display text."));

            //Create entries for static Information section.
            StringBuilder location = new StringBuilder("Location: ");
            location.Append(colLabel.Location);
            StringBuilder size = new StringBuilder("Size: ");
            size.Append(colLabel.Size);
            items.Add(new DesignerActionTextItem(location.ToString(),
                             "Information"));
            items.Add(new DesignerActionTextItem(size.ToString(),
                             "Information"));

            return items;
        }
    }


}